package com.am.server.common.util;

import cn.hutool.core.text.CharSequenceUtil;
import com.am.server.common.util.exception.NotFoundIndexParameterException;
import com.am.server.common.util.exception.NotFoundParameterException;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;

/**
 * @author 阮雪峰
 */
public class AspectUtils {
    private AspectUtils() {
    }

    /**
     * 切面方法通过参数名称获取参数值
     *
     * @param joinPoint     切面对象
     * @param parameterName 参数名称
     * @param <T>           参数值类型
     * @return T
     */
    public static <T> T getParameterValueByName(final JoinPoint joinPoint, final String parameterName) {
        if (joinPoint.getSignature() instanceof MethodSignature signature) {
            final String[] parameterNames = signature.getParameterNames();
            final Object[] args = joinPoint.getArgs();
            int index = 0;
            for (final String name : parameterNames) {
                if (CharSequenceUtil.equals(name, parameterName) && args[index] != null) {
                    return (T) args[index];
                }
                index++;
            }
            throw new NotFoundParameterException(parameterName);
        } else {
            throw new IllegalArgumentException(String.format("JoinPoint必须为MethodSignature，传入类型为：%s", joinPoint.getClass().getName()));
        }
    }

    /**
     * 获取切面方法第${index}参数值
     *
     * @param joinPoint 切面对象
     * @param index     参数索引
     * @param <T>       参数值类型
     * @return T
     */
    public static <T> T getParameterValueByIndex(final JoinPoint joinPoint, final int index) {
        if (joinPoint.getSignature() instanceof MethodSignature) {
            final Object[] args = joinPoint.getArgs();
            if (index < 0 || index >= args.length) {
                throw new NotFoundIndexParameterException(args.length, index);
            } else {
                return (T) args[index];
            }
        } else {
            throw new IllegalArgumentException(String.format("JoinPoint必须为MethodSignature，传入类型为：%s", joinPoint.getClass().getName()));
        }
    }
}
